package com.hwpt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hwpt.dto.admin.UserBasicInfoDTO;
import com.hwpt.dto.admin.UserListDTO;
import com.hwpt.dto.user.UserRegisterDTO;
import com.hwpt.entity.UserBasicInfo;
import com.hwpt.entity.UserDeviceInfo;
import com.hwpt.entity.UserEmergencyContact;
import com.hwpt.entity.UserRealNameAuth;
import com.hwpt.exception.AuthException;
import com.hwpt.mapper.UserBasicInfoMapper;
import com.hwpt.mapper.UserDeviceInfoMapper;
import com.hwpt.mapper.UserEmergencyContactMapper;
import com.hwpt.mapper.UserRealNameAuthMapper;
import com.hwpt.result.PageResult;
import com.hwpt.service.UserInfoService;
import com.hwpt.utils.IdGeneratorUtil;
import com.hwpt.utils.SCryptUtil;
import com.hwpt.vo.admin.UserBasicInfoVo;
import com.hwpt.vo.admin.UserListVo;
import com.hwpt.vo.user.UserAllInfoVO;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.extension.toolkit.Db.*;
import static com.hwpt.constant.ExceptionMessageConstant.*;
import static com.hwpt.constant.RedisKeyConstant.*;


@RequiredArgsConstructor
@Slf4j
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserBasicInfoMapper, UserBasicInfo> implements UserInfoService {

    private final UserBasicInfoMapper userBasicInfoMapper;
    private final UserRealNameAuthMapper userRealNameAuthMapper;
    private final UserEmergencyContactMapper userEmergencyContactMapper;
    private final SCryptUtil scryptUtil;
    private final RedisTemplate<String, Object> redisTemplate;
    private final UserDeviceInfoMapper userDeviceInfoMapper;

    @Override
    @Transactional
    public void registerUser(UserRegisterDTO userRegisterDTO) {
        String phone = userRegisterDTO.getPhone();
        String password = userRegisterDTO.getPassword();
        String confirmPwd = userRegisterDTO.getConfirmPassword();
        log.info("开始处理用户注册请求，手机号：{}", phone);

        checkPhoneNotRegistered(phone);

        if (!password.equals(confirmPwd)) {
            log.warn("注册失败：两次密码不一致，手机号：{}，输入密码：{},二次密码{}", phone, password, confirmPwd);
            throw new AuthException(PASSWORD_CONFIRM_NOT_MATCH);
        }

        LambdaQueryWrapper<UserBasicInfo> existQuery = new LambdaQueryWrapper<>();
        existQuery.eq(UserBasicInfo::getPhone, phone);
        long phoneCount = userBasicInfoMapper.selectCount(existQuery);
        if (phoneCount > 0) {
            log.warn("注册失败：手机号已注册，手机号：{}", phone);
            throw new AuthException(PHONE_EXIST);
        }

        String hanWangId = IdGeneratorUtil.generateHwId();
        String encryptedPwd = scryptUtil.encrypt(password);
        log.info("用户标识生成成功，手机号：{}，汉王ID：{}", phone, hanWangId);

        createUserBasicInfo(hanWangId, encryptedPwd, phone);
        createEmergencyContact(hanWangId);
        createRealNameAuth(hanWangId);

        afterRegisterSuccess(phone);
        log.info("用户注册成功，手机号：{}，汉王ID：{}", phone, hanWangId);

    }


    @Transactional
    @Override
    public void syncBasicInfo(UserAllInfoVO userAllInfoVO) {
        log.info("开始同步用户基本信息");

        // 先解析JWT
        if (ObjectUtils.isEmpty(userAllInfoVO)) {
            log.info("同步用户基本信息失败，用户信息为空");
            throw new AuthException(USER_INFO_EMPTY);
        }


        String hanWangId = userAllInfoVO.getHanWangId();
        if (hanWangId == null) {
            log.info("同步用户基本信息失败，用户ID不存在");
            throw new AuthException(USER_ID_NOT_FOUND);
        }

        // 更新信息 - 使用Lambda表达式根据hanWangId更新
        UserBasicInfo userBasicInfo = new UserBasicInfo();
        UserDeviceInfo userDeviceInfo = new UserDeviceInfo();
        UserEmergencyContact userEmergencyContact = new UserEmergencyContact();
        UserRealNameAuth userRealNameAuth = new UserRealNameAuth();

        BeanUtils.copyProperties(userAllInfoVO, userBasicInfo);
        BeanUtils.copyProperties(userAllInfoVO, userDeviceInfo);
        BeanUtils.copyProperties(userAllInfoVO, userEmergencyContact);
        BeanUtils.copyProperties(userAllInfoVO, userRealNameAuth);

        // 使用LambdaUpdateWrapper更新用户基本信息
        LambdaUpdateWrapper<UserBasicInfo> basicInfoWrapper = new LambdaUpdateWrapper<>();
        basicInfoWrapper.eq(UserBasicInfo::getHanWangId, hanWangId);
        userBasicInfoMapper.update(userBasicInfo, basicInfoWrapper);
        log.info("用户基本信息同步成功");

        // 使用LambdaUpdateWrapper更新用户设备信息
        LambdaUpdateWrapper<UserDeviceInfo> deviceInfoWrapper = new LambdaUpdateWrapper<>();
        deviceInfoWrapper.eq(UserDeviceInfo::getHanWangId, hanWangId);
        userDeviceInfoMapper.update(userDeviceInfo, deviceInfoWrapper);
        log.info("用户设备信息同步成功");

        // 使用LambdaUpdateWrapper更新用户紧急联系人信息
        LambdaUpdateWrapper<UserEmergencyContact> emergencyContactWrapper = new LambdaUpdateWrapper<>();
        emergencyContactWrapper.eq(UserEmergencyContact::getHanWangId, hanWangId);
        userEmergencyContactMapper.update(userEmergencyContact, emergencyContactWrapper);
        log.info("用户紧急联系人信息同步成功");

        // 使用LambdaUpdateWrapper更新用户实名认证信息
        LambdaUpdateWrapper<UserRealNameAuth> realNameAuthWrapper = new LambdaUpdateWrapper<>();
        realNameAuthWrapper.eq(UserRealNameAuth::getHanWangId, hanWangId);
        userRealNameAuthMapper.update(userRealNameAuth, realNameAuthWrapper);
        log.info("用户实名认证信息同步成功");
    }


    @Override
    public UserBasicInfo getUserByPhone(String phone) {
        LambdaQueryWrapper<UserBasicInfo> query = new LambdaQueryWrapper<>();
        query.eq(UserBasicInfo::getPhone, phone);
        return userBasicInfoMapper.selectOne(query);
    }

    @Override
    public UserBasicInfo getUserByHanWangId(String hanWangId) {
        LambdaQueryWrapper<UserBasicInfo> query = new LambdaQueryWrapper<>();
        query.eq(UserBasicInfo::getHanWangId, hanWangId);
        return userBasicInfoMapper.selectOne(query);
    }

    @Override
    public UserAllInfoVO getUserAllInfo(String hanWangId) {
        UserBasicInfo user = getUserByHanWangId(hanWangId);
        if (user == null) {
            return null;
        }

        UserRealNameAuth userRealInfo = getUserRealNameAuth(hanWangId);
        UserEmergencyContact userEmergencyInfo = getUserEmergencyContact(hanWangId);

        UserAllInfoVO userAllInfoVO = new UserAllInfoVO();
        BeanUtils.copyProperties(user, userAllInfoVO);
        BeanUtils.copyProperties(userRealInfo, userAllInfoVO);
        BeanUtils.copyProperties(userEmergencyInfo, userAllInfoVO);

        return userAllInfoVO;
    }

    @Override
    public void checkPhoneRegistered(String phone) {
        checkPhoneStatus(phone, true);
    }

    @Override
    public void checkPhoneNotRegistered(String phone) {
        checkPhoneStatus(phone, false);
    }


    private UserRealNameAuth getUserRealNameAuth(String hanWangId) {
        LambdaQueryWrapper<UserRealNameAuth> query = new LambdaQueryWrapper<>();
        query.eq(UserRealNameAuth::getHanWangId, hanWangId);
        return userRealNameAuthMapper.selectOne(query);
    }

    private UserEmergencyContact getUserEmergencyContact(String hanWangId) {
        LambdaQueryWrapper<UserEmergencyContact> query = new LambdaQueryWrapper<>();
        query.eq(UserEmergencyContact::getHanWangId, hanWangId);
        return userEmergencyContactMapper.selectOne(query);
    }

    private void createUserBasicInfo(String hanWangId, String encryptedPwd, String phone) {
        UserBasicInfo userBasicInfo = UserBasicInfo.builder()
                .hanWangId(hanWangId)
                .password(encryptedPwd)
                .phone(phone)
                .registerTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        userBasicInfoMapper.insert(userBasicInfo);
    }

    private void createEmergencyContact(String hanWangId) {
        UserEmergencyContact userEmergencyContact = UserEmergencyContact.builder()
                .hanWangId(hanWangId)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        userEmergencyContactMapper.insert(userEmergencyContact);
    }

    private void createRealNameAuth(String hanWangId) {
        UserRealNameAuth userRealNameAuth = UserRealNameAuth.builder()
                .hanWangId(hanWangId)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        userRealNameAuthMapper.insert(userRealNameAuth);
    }

    private void checkPhoneStatus(String phone, boolean shouldBeRegistered) {
        String registeredKey = REGISTERED_PHONE_KEY_PREFIX + phone;
        String unregisteredKey = UNREGISTERED_PHONE_KEY_PREFIX + phone;

        if (!shouldBeRegistered) {
            Object cachedRegistered = redisTemplate.opsForValue().get(registeredKey);
            if (!ObjectUtils.isEmpty(cachedRegistered)) {
                log.warn("校验失败：手机号已注册（缓存命中），手机号：{}", phone);
                throw new AuthException(PHONE_EXIST);
            }

            LambdaQueryWrapper<UserBasicInfo> query = new LambdaQueryWrapper<>();
            query.eq(UserBasicInfo::getPhone, phone);
            UserBasicInfo user = userBasicInfoMapper.selectOne(query);

            if (user != null) {
                redisTemplate.opsForValue().set(registeredKey, phone, 1, TimeUnit.DAYS);
                redisTemplate.delete(unregisteredKey);
                log.warn("校验失败：手机号已注册（数据库命中），手机号：{}", phone);
                throw new AuthException(PHONE_EXIST);
            } else {
                redisTemplate.opsForValue().set(unregisteredKey, phone, 1, TimeUnit.DAYS);
            }
        } else {
            Object cachedUnregistered = redisTemplate.opsForValue().get(unregisteredKey);
            if (!ObjectUtils.isEmpty(cachedUnregistered)) {
                LambdaQueryWrapper<UserBasicInfo> confirmQuery = new LambdaQueryWrapper<>();
                confirmQuery.eq(UserBasicInfo::getPhone, phone);
                UserBasicInfo confirmUser = userBasicInfoMapper.selectOne(confirmQuery);

                if (ObjectUtils.isEmpty(confirmUser)) {
                    log.warn("校验失败：手机号未注册（缓存+DB一致），手机号：{}", phone);
                    throw new AuthException(PHONE_NOT_REGISTERED);
                } else {
                    log.warn("校验发现缓存不一致，自动修复：{}", phone);
                    redisTemplate.opsForValue().set(registeredKey, phone, 1, TimeUnit.DAYS);
                    redisTemplate.delete(unregisteredKey);
                }
            }

            LambdaQueryWrapper<UserBasicInfo> query = new LambdaQueryWrapper<>();
            query.eq(UserBasicInfo::getPhone, phone);
            UserBasicInfo user = userBasicInfoMapper.selectOne(query);

            if (ObjectUtils.isEmpty(user)) {
                redisTemplate.opsForValue().set(unregisteredKey, phone, 1, TimeUnit.DAYS);
                log.warn("校验失败：手机号未注册（数据库命中），手机号：{}", phone);
                throw new AuthException("手机号未注册，请先注册");
            } else {
                redisTemplate.opsForValue().set(registeredKey, phone, 1, TimeUnit.DAYS);
            }
        }
    }

    private void afterRegisterSuccess(String phone) {
        String registeredKey = REGISTERED_PHONE_KEY_PREFIX + phone;
        String unregisteredKey = UNREGISTERED_PHONE_KEY_PREFIX + phone;

        redisTemplate.opsForValue().set(registeredKey, phone, 1, TimeUnit.DAYS);
        redisTemplate.delete(unregisteredKey);

        log.info("注册后缓存更新完成，手机号：{}", phone);
    }

    /*分页查询用户+条件筛选*/
    @Override
    public PageResult<UserListVo> list(UserListDTO userListDTO) {
        log.info("开始查询用户列表，参数: {}", userListDTO);

        try {
            // 1. 设置分页参数
            int pageNum = (userListDTO.getPage() == null || userListDTO.getPage() <= 0) ? 1 : userListDTO.getPage();
            int pageSize = (userListDTO.getPageSize() == null || userListDTO.getPageSize() <= 0) ? 10 : userListDTO.getPageSize();

            log.info("分页参数 - pageNum: {}, pageSize: {}", pageNum, pageSize);

            // 2. 构建查询条件
            QueryWrapper<UserBasicInfo> queryWrapper = buildQueryWrapper(userListDTO);

            // 3. 执行分页查询
            Page<UserBasicInfo> page = new Page<>(pageNum, pageSize);
            Page<UserBasicInfo> resultPage = userBasicInfoMapper.selectPage(page, queryWrapper);

            log.info("查询结果 - 总记录数: {}, 当前页记录数: {}", resultPage.getTotal(), resultPage.getRecords().size());

            // 4. 转换为VO列表
            List<UserListVo> voList = this.convertToVOList(resultPage.getRecords());

            // 5. 构建分页结果
            return this.buildPageResult(voList, resultPage);

        } catch (Exception e) {
            log.error("查询用户列表异常: ", e);
            return buildEmptyPageResult();
        }
    }

    private QueryWrapper<UserBasicInfo> buildQueryWrapper(UserListDTO dto) {
        QueryWrapper<UserBasicInfo> queryWrapper = new QueryWrapper<>();
        log.info("开始构建查询条件，参数: {}", dto);

        boolean hasCondition = false;

        // 关键词搜索
        if (dto != null && StringUtils.isNotBlank(dto.getKeyword())) {
            log.info("添加关键词搜索条件: keyword={}, searchType={}", dto.getKeyword(), dto.getSearchType());
            buildSearchCondition(queryWrapper, dto.getSearchType(), dto.getKeyword().trim());
            hasCondition = true;
        }

        // 性别筛选 - 使用字符串字段名
        if (dto != null && dto.getGender() != null) {
            log.info("添加性别筛选条件: gender={}", dto.getGender());
            queryWrapper.eq("gender", dto.getGender());
            hasCondition = true;
        }

        // 地区筛选 - 使用字符串字段名
        if (dto != null && StringUtils.isNotBlank(dto.getRegion())) {
            log.info("添加地区筛选条件: region={}", dto.getRegion());
            queryWrapper.like("country_region", dto.getRegion());
            hasCondition = true;
        }

        // 时间范围筛选 - 使用字符串字段名
        if (dto != null && dto.getStartDate() != null) {
            log.info("添加开始时间筛选条件: startDate={}", dto.getStartDate());
            queryWrapper.ge("register_time", dto.getStartDate());
            hasCondition = true;
        }
        if (dto != null && dto.getEndDate() != null) {
            log.info("添加结束时间筛选条件: endDate={}", dto.getEndDate());
            queryWrapper.le("register_time", dto.getEndDate());
            hasCondition = true;
        }


        // 如果没有查询条件，查询所有数据
        if (!hasCondition) {
            log.info("无查询条件，查询所有用户数据");
            queryWrapper.isNotNull("user_id");
        }

        // 排序 - 使用字符串字段名
        queryWrapper.orderByDesc("register_time");
        log.info("最终查询条件: {}", queryWrapper.getSqlSegment());

        return queryWrapper;
    }

    private void buildSearchCondition(QueryWrapper<UserBasicInfo> queryWrapper, String searchType, String keyword) {
        log.info("构建搜索条件: searchType={}, keyword={}", searchType, keyword);

        if (StringUtils.isBlank(keyword)) {
            log.warn("搜索关键词为空，跳过搜索条件构建");
            return;
        }

        // 如果searchType为空，搜索所有字段
        if (StringUtils.isBlank(searchType)) {
            log.info("搜索所有字段");
            queryWrapper.and(wrapper ->
                    wrapper.like("hanwang_id", keyword)
                            .or().like("phone", keyword)
                            .or().like("nickname", keyword)
            );
            return;
        }

        switch (searchType) {
            case "hwId":
                queryWrapper.like("hanwang_id", keyword);
                log.info("添加汉王ID搜索条件: {}", keyword);
                break;
            case "phone":
                queryWrapper.like("phone", keyword);
                log.info("添加手机号搜索条件: {}", keyword);
                break;
            case "name":
                queryWrapper.like("nickname", keyword); // 先用昵称代替
                log.info("添加姓名搜索条件(使用昵称): {}", keyword);
                break;
            case "nickname":
                queryWrapper.like("nickname", keyword);
                log.info("添加昵称搜索条件: {}", keyword);
                break;
            default:
                log.warn("未知搜索类型: {}，使用默认搜索", searchType);
                queryWrapper.and(wrapper ->
                        wrapper.like("hanwang_id", keyword)
                                .or().like("phone", keyword)
                                .or().like("nickname", keyword)
                );
        }
    }

    private List<UserListVo> convertToVOList(List<UserBasicInfo> userList) {
        if (userList == null || userList.isEmpty()) {
            log.info("用户列表为空，无需转换");
            return new ArrayList<>();
        }

        log.info("开始转换VO列表，用户数量: {}", userList.size());

        return userList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    private UserListVo convertToVO(UserBasicInfo user) {
        UserListVo vo = new UserListVo();

        // 基础信息映射
        vo.setUserId(user.getUserId());
        vo.setHanWangId(user.getHanWangId());
        vo.setPhone(user.getPhone());
        vo.setNickname(user.getNickname());
        vo.setGender(user.getGender());
        vo.setRegisterTime(user.getRegisterTime());
        vo.setCountryRegion(user.getCountryRegion());

        // 设置文本字段
        vo.setGenderText(getGenderText(user.getGender()));

        // 查询真实姓名
        try {
            UserRealNameAuth auth = userRealNameAuthMapper.selectById(user.getHanWangId());
            if (auth != null) {
                vo.setRealName(auth.getRealName());
                vo.setAuthStatus(auth.getAuthStatus());
                vo.setAuthStatusText(getAuthStatusText(auth.getAuthStatus()));
            } else {
                vo.setRealName("");
                vo.setAuthStatus(0);
                vo.setAuthStatusText("未认证");
            }
        } catch (Exception e) {
            log.error("查询认证信息异常: ", e);
            vo.setRealName("");
            vo.setAuthStatus(0);
            vo.setAuthStatusText("未认证");
        }

        return vo;
    }

    private PageResult<UserListVo> buildPageResult(List<UserListVo> list, Page<UserBasicInfo> page) {
        PageResult<UserListVo> result = new PageResult<>();
        result.setList(list);
        result.setTotal(page.getTotal());
        result.setPage((int) page.getCurrent());
        result.setPageSize((int) page.getSize());
        result.setTotalPages((int) page.getPages());
        return result;
    }

    private PageResult<UserListVo> buildEmptyPageResult() {
        PageResult<UserListVo> result = new PageResult<>();
        result.setList(new ArrayList<>());
        result.setTotal(0L);
        result.setPage(1);
        result.setPageSize(10);
        result.setTotalPages(0);
        return result;
    }

    // 辅助方法
    private String getGenderText(Integer gender) {
        if (gender == null) return "未知";
        switch (gender) {
            case 1: return "男";
            case 2: return "女";
            case 0: return "未填写";
            default: return "未知";
        }
    }

    private String getAuthStatusText(Integer authStatus) {
        if (authStatus == null) return "未认证";
        switch (authStatus) {
            case 0: return "未认证";
            case 1: return "已认证";
            case 2: return "认证中";
            case 3: return "认证失败";
            default: return "未认证";
        }
    }
    /*获取用户详细信息*/
    @Override
    public UserBasicInfoVo getUser(String userId) {
        log.info("开始查询用户详细信息，用户ID: {}", userId);

        try {
            // 1. 查询用户基本信息
            UserBasicInfo userBasicInfo = this.getById(userId);
            if (userBasicInfo == null) {
                log.warn("用户不存在，用户ID: {}", userId);
                throw new RuntimeException("用户不存在");
            }

            log.info("查询到用户基本信息: userId={}, hanWangId={}", userBasicInfo.getUserId(), userBasicInfo.getHanWangId());

            // 2. 创建VO对象并设置合理的默认值
            UserBasicInfoVo userBasicInfoVo = new UserBasicInfoVo();
            BeanUtils.copyProperties(userBasicInfo, userBasicInfoVo);

            // 设置默认值
            userBasicInfoVo.setRealName("未设置");
            userBasicInfoVo.setIdCard("未设置");
            userBasicInfoVo.setAuthStatus(0);
            userBasicInfoVo.setAuthStatusText("未认证");
            userBasicInfoVo.setMachineSerial("未设置");
            userBasicInfoVo.setIpAddress("未设置");
            userBasicInfoVo.setLastLoginTime(null);
            userBasicInfoVo.setContactName("未设置");
            userBasicInfoVo.setContactMobile("未设置");
            userBasicInfoVo.setRelationship("未设置");

            String hanWangId = userBasicInfo.getHanWangId();

            // 3. 查询实名认证信息 - 添加详细的调试信息
            log.info("=== 开始查询实名认证信息 ===");
            log.info("查询条件: hanwang_id = {}", hanWangId);

            QueryWrapper<UserRealNameAuth> authWrapper = new QueryWrapper<>();
            authWrapper.eq("hanwang_id", hanWangId);

            UserRealNameAuth userRealNameAuth = userRealNameAuthMapper.selectOne(authWrapper);

            if (userRealNameAuth != null) {
                log.info("✅ 查询到实名认证记录: auth_id={}", userRealNameAuth.getAuthId());
                log.info("实名认证详细信息 - real_name: {}, id_card: {}, auth_status: {}",
                        userRealNameAuth.getRealName(),
                        userRealNameAuth.getIdCard(),
                        userRealNameAuth.getAuthStatus());

                // 安全设置字段值
                if (StringUtils.isNotBlank(userRealNameAuth.getRealName())) {
                    userBasicInfoVo.setRealName(userRealNameAuth.getRealName());
                }
                if (StringUtils.isNotBlank(userRealNameAuth.getIdCard())) {
                    userBasicInfoVo.setIdCard(userRealNameAuth.getIdCard());
                }
                if (userRealNameAuth.getAuthStatus() != null) {
                    userBasicInfoVo.setAuthStatus(userRealNameAuth.getAuthStatus());
                    userBasicInfoVo.setAuthStatusText(getAuthStatusText(userRealNameAuth.getAuthStatus()));
                }
                if (userRealNameAuth.getCreateTime() != null) {
                    userBasicInfoVo.setAuthTime(userRealNameAuth.getCreateTime());
                }
            } else {
                log.warn("hanWangId: {}", hanWangId);
                log.info("可能的原因: 1. 表中无此记录 2. hanwang_id不匹配 3. 数据未同步");
            }

            // 4. 查询设备信息 - 添加详细的调试信息
            log.info("=== 开始查询设备信息 ===");
            QueryWrapper<UserDeviceInfo> deviceWrapper = new QueryWrapper<>();
            deviceWrapper.eq("hanwang_id", hanWangId)
                    .orderByDesc("last_login_time")
                    .last("LIMIT 1");

            UserDeviceInfo userDeviceInfo = userDeviceInfoMapper.selectOne(deviceWrapper);

            if (userDeviceInfo != null) {
                log.info("查询到设备信息记录: device_id={}", userDeviceInfo.getDeviceId());
                log.info("设备详细信息 - machine_serial: {}, ip_address: {}, last_login_time: {}",
                        userDeviceInfo.getMachineSerial(),
                        userDeviceInfo.getIpAddress(),
                        userDeviceInfo.getLastLoginTime());

                if (StringUtils.isNotBlank(userDeviceInfo.getMachineSerial())) {
                    userBasicInfoVo.setMachineSerial(userDeviceInfo.getMachineSerial());
                }
                if (StringUtils.isNotBlank(userDeviceInfo.getIpAddress())) {
                    userBasicInfoVo.setIpAddress(userDeviceInfo.getIpAddress());
                }
                if (userDeviceInfo.getLastLoginTime() != null) {
                    userBasicInfoVo.setLastLoginTime(userDeviceInfo.getLastLoginTime());
                }
            } else {
                log.warn("hanWangId: {}", hanWangId);
            }

            // 5. 设置文本字段
            userBasicInfoVo.setGenderText(getGenderText(userBasicInfo.getGender()));

            // 6. 处理生日字段
            if (userBasicInfo.getBirthday() != null) {
                userBasicInfoVo.setBirthday(userBasicInfo.getBirthday().toString());
            }

            log.info("=== 最终用户信息 ===");
            log.info("基础信息: userId={}, phone={}, nickname={}",
                    userBasicInfoVo.getUserId(), userBasicInfoVo.getPhone(), userBasicInfoVo.getNickname());
            log.info("认证信息: realName={}, authStatus={}",
                    userBasicInfoVo.getRealName(), userBasicInfoVo.getAuthStatus());
            log.info("设备信息: machineSerial={}, ipAddress={}",
                    userBasicInfoVo.getMachineSerial(), userBasicInfoVo.getIpAddress());

            return userBasicInfoVo;

        } catch (Exception e) {
            log.error("查询用户详细信息异常，用户ID: {}", userId, e);
            throw new RuntimeException("查询用户信息失败");
        }
    }

    /*添加用户*/
    @Override
    public Long addUser(UserBasicInfo userBasicInfo) {
        // 校验用户信息
        validateUserInfo(userBasicInfo);
        String hanWangId = IdGeneratorUtil.generateHwId();
        // 创建用户基本信息
        UserBasicInfo userBasic = new UserBasicInfo();
        userBasic.setHanWangId(hanWangId);
        userBasic.setPassword(scryptUtil.encrypt(userBasicInfo.getPassword()));
        userBasic.setPhone(userBasicInfo.getPhone());
        userBasic.setNickname(userBasicInfo.getNickname());
        userBasic.setGender(userBasicInfo.getGender());
        userBasic.setBirthday(userBasicInfo.getBirthday());
        userBasic.setCountryRegion(userBasicInfo.getCountryRegion());
        userBasic.setEmail(userBasicInfo.getEmail());
        userBasic.setRegisterTime(LocalDateTime.now());
        userBasic.setUpdateTime(LocalDateTime.now());
        userBasic.setAvatarUrl(""); // 设置默认头像URL
        // 保存用户基本信息
        boolean saveResult = baseMapper.insert(userBasic) > 0;
        if (!saveResult) {
            throw new RuntimeException("用户添加失败");
        }
        // 同时创建紧急联系人和实名认证记录
        createEmergencyContact(hanWangId);
        createRealNameAuth(hanWangId);

        log.info("用户添加成功，用户ID：{}", userBasicInfo.getUserId());
        return userBasicInfo.getUserId();
    }

    private void validateUserInfo(UserBasicInfo userBasicInfo) {
        // 检查手机号是否已存在
        LambdaQueryWrapper<UserBasicInfo> phoneQuery = new LambdaQueryWrapper<>();
        phoneQuery.eq(UserBasicInfo::getPhone, userBasicInfo.getPhone());
        if (userBasicInfoMapper.selectCount(phoneQuery) > 0) {
            throw new AuthException(PHONE_EXIST);
        }
    }

    /*更新用户信息*/
    @Override
    public void updateUser(String userId, UserBasicInfoDTO userBasicInfoDTO) {
        // 检查用户是否存在
        UserBasicInfo existingUser = userBasicInfoMapper.selectById(userId);
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 校验手机号唯一性（如果修改了手机号）
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getPhone()) &&
                !userBasicInfoDTO.getPhone().equals(existingUser.getPhone())) {
            validatePhoneUnique(userBasicInfoDTO.getPhone());
        }

        // 校验邮箱唯一性（如果修改了邮箱）
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getEmail()) &&
                !userBasicInfoDTO.getEmail().equals(existingUser.getEmail())) {
            validateEmailUnique(userBasicInfoDTO.getEmail());
        }

        // 构建更新对象
        UserBasicInfo updateInfo = new UserBasicInfo();
        updateInfo.setUserId(Long.valueOf(userId)); // 转换为 Long 类型
        // 只更新非空的字段
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getPhone())) {
            updateInfo.setPhone(userBasicInfoDTO.getPhone());
        }
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getNickname())) {
            updateInfo.setNickname(userBasicInfoDTO.getNickname());
        }
        if (userBasicInfoDTO.getGender() != null) {
            updateInfo.setGender(userBasicInfoDTO.getGender());
        }
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getBirthday())) {
            updateInfo.setBirthday(LocalDate.parse(userBasicInfoDTO.getBirthday()));
        }
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getCountryRegion())) {
            updateInfo.setCountryRegion(userBasicInfoDTO.getCountryRegion());
        }
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getEmail())) {
            updateInfo.setEmail(userBasicInfoDTO.getEmail());
        }
        if (org.springframework.util.StringUtils.hasText(userBasicInfoDTO.getAvatarUrl())) {
            updateInfo.setAvatarUrl(userBasicInfoDTO.getAvatarUrl());
        }
        updateInfo.setUpdateTime(LocalDateTime.now());

        // 执行更新
        int updateResult = userBasicInfoMapper.updateById(updateInfo);
        if (updateResult <= 0) {
            throw new RuntimeException("用户信息更新失败");
        }
        log.info("用户信息更新成功，用户ID: {}", userId);
    }
    /**
     * 校验手机号唯一性
     */
    private void validatePhoneUnique(String phone) {
        LambdaQueryWrapper<UserBasicInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBasicInfo::getPhone, phone);
        if (getOne(queryWrapper) != null) {
            throw new RuntimeException("手机号已存在");
        }
    }
    /**
     * 校验邮箱唯一性
     */
    private void validateEmailUnique(String email) {
        LambdaQueryWrapper<UserBasicInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserBasicInfo::getEmail, email);
        if (getOne(queryWrapper) != null) {
            throw new RuntimeException("邮箱已存在");
        }
    }
    /*删除用户*/
    @Override
    public void deleteUser(String userId) {
        // 检查用户是否存在
        UserBasicInfo existingUser = userBasicInfoMapper.selectById(userId);
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }

        // 使用实体类删除，而不是直接使用ID字符串
        UserBasicInfo userToDelete = new UserBasicInfo();
        userToDelete.setUserId(Long.valueOf(userId)); // 假设userId是Long类型，根据实际情况调整

        // 执行删除操作
        boolean deleteResult = removeById(userToDelete);
        if (!deleteResult) {
            throw new RuntimeException("用户删除失败");
        }

        log.info("用户删除成功，用户ID: {}", userId);
        // 可选：同时删除关联数据（如紧急联系人、实名认证等）
        deleteUserRelatedData(Long.valueOf(userId));
    }
    /**
     * 删除用户关联数据
     */
    private void deleteUserRelatedData(Long userId) {
        try {
            // 删除其他关联数据...
            log.info("已删除用户 {} 的关联数据", userId);
        } catch (Exception e) {
            log.warn("删除用户关联数据失败，用户ID: {}, 错误: {}", userId, e.getMessage());
        }
    }
    /*批量删除用户*/

    @Override
    public void batchDeleteUsers(List<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            throw new RuntimeException("用户ID列表不能为空");
        }

        // 查询存在的用户
        List<UserBasicInfo> existingUsers = userBasicInfoMapper.selectBatchIds(userIds);
        if (existingUsers.size() != userIds.size()) {
            Set<Long> existingIds = existingUsers.stream()
                    .map(UserBasicInfo::getUserId)
                    .collect(Collectors.toSet());
            List<Long> notExistIds = userIds.stream()
                    .filter(id -> !existingIds.contains(id))
                    .collect(Collectors.toList());
            throw new RuntimeException("部分用户不存在，ID: " + notExistIds);
        }

        // 删除主表
        userBasicInfoMapper.deleteBatchIds(userIds);

        log.info("批量删除成功，删除用户数量: {}", userIds.size());

        // 删除关联数据
        batchDeleteUserRelatedData(userIds);
    }
    /**
     * 批量删除用户关联数据
     */
    private void batchDeleteUserRelatedData(List<Long> userIds) {
        try {
            // 批量删除紧急联系人记录
            // emergencyContactService.batchDeleteByUserIds(userIds);

            // 批量删除实名认证记录
            // realNameAuthService.batchDeleteByUserIds(userIds);

            log.info("已批量删除 {} 个用户的关联数据", userIds.size());
        } catch (Exception e) {
            log.warn("批量删除用户关联数据失败，错误: {}", e.getMessage());
            // 这里可以选择记录日志但不抛出异常，避免影响主删除操作
        }
    }
    /**
     * 安全的批量删除方法（忽略不存在的用户）
     */
    public void batchDeleteUsersSafely(List<Long> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return;
        }
        List<UserBasicInfo> existingUsers = listByIds(userIds);
        if (!existingUsers.isEmpty()) {
            List<Long> existingIds = existingUsers.stream()
                    .map(UserBasicInfo::getUserId)
                    .collect(Collectors.toList());
            removeByIds(existingIds);
            log.info("安全批量删除成功，实际删除用户数量: {}", existingIds.size());
            batchDeleteUserRelatedData(existingIds);
        }
    }
}